﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Drawing;

namespace FastGraphClustering_13._12
{
    class Kernel_K_Means 
    {
        public int numOfClusters, ClusterArrayActualLength;
        public int numOfNodesKernel, new_numOfNodesKernel=0;
        public int [] weightOfNode ,ClusterNode;
        public Matrix kernelMatrix;
         double Sigma;
        Matrix UnitMatrix;
        Matrix D,DInverse,SigmaDInverse;
        public Cluster [] ClusterArray;
        Random rand = new Random();
        public  Point [] kernalCoard;
        int[] bestCluster ;
       public  int ErrorFlag = 0;
       public int m_kMatrix = -1;
       public static int kernelID = 0;
       public int run_test_flag1 = 0;
       public Boolean InterestsExists;       

        public Network net;
       
        public Kernel_K_Means(int choosenMatrix, int numOfClusters,Network currentNetwork,double enteredSigma , int flag )
         {
             InterestsExists = false;
             kernelID++;
             this.net = currentNetwork;
             this.numOfClusters = numOfClusters;
             this.DInverse = new Matrix(net.adjacnyMatrix.Data.GetLength(1));
             this.D = new Matrix(net.adjacnyMatrix.Data.GetLength(1));
             this.SigmaDInverse = new Matrix(net.adjacnyMatrix.Data.GetLength(1));
             this.UnitMatrix = new Matrix(net.adjacnyMatrix.Data.GetLength(1));
             this.Sigma = enteredSigma;
             this.ClusterNode = new int[net.adjacnyMatrix.Data.GetLength(1)];
             this.weightOfNode = new int[net.adjacnyMatrix.Data.GetLength(1)];
             this.kernalCoard = new Point[net.adjacnyMatrix.Data.GetLength(1)]; //Array of points in the size as the whole network
             this.kernelMatrix = new Matrix(net.adjacnyMatrix.Data.GetLength(1));
             this.numOfNodesKernel = net.numOfNodesKernel_new;
             this.bestCluster = new int[net.adjacnyMatrix.Data.GetLength(1)];
             this.m_kMatrix = choosenMatrix;
             this.run_test_flag1 = flag;
             for (int i = 0; i <net.adjacnyMatrix.Data.GetLength(1); i++)
             {
                 kernalCoard[i].X = 0;
                 kernalCoard[i].Y = 0;
                 this.ClusterNode[i] = -1;
             }
             for (int i = 0; i < net.numOfNodes; i++)
             {
                 this.UnitMatrix.Data[i, i] = this.Sigma; //calculate sigma*UnitMatrix
                 for (int j = 0; j < net.numOfNodes; j++) 
                 {  
                     this.DInverse.Data[i, j] = 0;
                     this.SigmaDInverse.Data[i, j] = 0;
                 }
             }
             ClusterArrayActualLength = numOfClusters;
             this.ClusterArray = new Cluster[Main_Window.MaxNumOfClustersPossible];


             for (int i = 0; i < numOfClusters; i++)
             {
                 this.ClusterArray[i] = new Cluster(net.numOfNodes, i+1);
             }
             if (enteredSigma != -99)
             {
                 calcKernekMatrix(choosenMatrix);

                 RunKernelKMeans(numOfClusters, flag); // Run the algorithm !!        
             }
         }


        public void DrawPecenteges(int[] ClusterSorted, Graphics ClusteredImage, Boolean FromGraclus)
        {
            int MaxX = Main_Window.imgXClusteredGraph, MaxY = Main_Window.imgYClusteredGraph;
            MaxX -= 35; MaxY -= 35;
            int tempLength = ClusterArrayActualLength, m = -1, w = 220, h = 34, x = -1, y = -1;
            if (tempLength > 9)
                tempLength = 9;
            string edgesperSTR;
            ClusteredImage.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
            Font font1 = new Font("Old English Text MT", 18, FontStyle.Italic);
            Font font2 = new Font("Old English Text MT", 12, FontStyle.Bold);
            Brush Brush = Brushes.PaleTurquoise, RectBrush = Brushes.CornflowerBlue;
            Pen rectPen = Pens.PaleTurquoise;
            if (FromGraclus)
            {
                rectPen = Pens.PeachPuff;
                Brush = Brushes.PeachPuff;
                RectBrush = Brushes.RosyBrown;
            }
            switch (tempLength)
            {
                case 1:
                    {
                        edgesperSTR = Convert.ToString(Convert.ToInt32(ClusterArray[0].edgesPercent));
                        ClusteredImage.FillEllipse(RectBrush, 10, 85, w, h);
                        ClusteredImage.DrawString((" 1 : " + edgesperSTR + "%"), font1, Brush, new PointF(20, 20));
                    }
                    break;
                case 2:
                    {
                        for (int i = 0; i < 2; i++)// iterate as number of clusters
                        {
                            m = ClusterSorted[i];
                            if (i == 0)
                            {
                                ClusteredImage.FillEllipse(RectBrush, 10, 85, w, h);
                                ClusteredImage.DrawEllipse(rectPen, 10, 85, w, h);
                                if (ClusterArray[m].numOfUsers1stInterests > 0.5)
                                {
                                    edgesperSTR = ClusterArray[m].interest1stpercent;
                                    edgesperSTR += "% " + ClusterArray[m].Interests1st;
                                }
                                else edgesperSTR = "No";
                                ClusteredImage.DrawString(((m + 1) + ") " + edgesperSTR), font1, Brush, new PointF(10, 85));
                            }
                            else if (i == 1)
                            {

                                ClusteredImage.FillEllipse(RectBrush, MaxX / 2 + 30, 85, w, h);
                                ClusteredImage.DrawEllipse(rectPen, MaxX / 2 + 30, 85, w, h);
                                if (ClusterArray[m].numOfUsers1stInterests > 0.5)
                                {
                                    edgesperSTR = ClusterArray[m].interest1stpercent;
                                    edgesperSTR += "% " + ClusterArray[m].Interests1st;
                                }
                                else edgesperSTR = "No";
                                ClusteredImage.DrawString(((m + 1) + ") " + edgesperSTR), font1, Brush, new PointF(MaxX / 2 + 30, 85));
                            }
                        }
                    }
                    break;
                case 3:
                    {
                        for (int i = 0; i < 3; i++)// iterate as number of clusters
                        {
                            m = ClusterSorted[i];
                            if (i == 0)
                            {
                                ClusteredImage.FillEllipse(RectBrush, 0, 0, w, h);
                                ClusteredImage.DrawEllipse(rectPen, 0, 0, w, h);
                                if (ClusterArray[m].numOfUsers1stInterests > 0.5)
                                {
                                    edgesperSTR = ClusterArray[m].interest1stpercent;
                                    edgesperSTR += "% " + ClusterArray[m].Interests1st;
                                }
                                else edgesperSTR = "No";
                                ClusteredImage.DrawString(((m + 1) + ") " + edgesperSTR), font1, Brush, new PointF(0, 0));
                            }
                            else if (i == 1)
                            {
                                ClusteredImage.FillEllipse(RectBrush, 580, 0, w, h);
                                ClusteredImage.DrawEllipse(rectPen, 580, 0, w, h);
                                if (ClusterArray[m].numOfUsers1stInterests > 0.5)
                                {
                                    edgesperSTR = ClusterArray[m].interest1stpercent;
                                    edgesperSTR += "% " + ClusterArray[m].Interests1st;
                                }
                                else edgesperSTR = "No";
                                ClusteredImage.DrawString(((m + 1) + ") " + edgesperSTR), font1, Brush, new PointF(580, 0));
                            }
                            else if (i == 2)
                            {
                                ClusteredImage.FillEllipse(RectBrush, 292, MaxY - 35, w, h);
                                ClusteredImage.DrawEllipse(rectPen, 292, MaxY - 35, w, h);
                                if (ClusterArray[m].numOfUsers1stInterests > 0.5)
                                {
                                    edgesperSTR = ClusterArray[m].interest1stpercent;
                                    edgesperSTR += "% " + ClusterArray[m].Interests1st;
                                }
                                else edgesperSTR = "No";
                                ClusteredImage.DrawString(((m + 1) + ") " + edgesperSTR), font1, Brush, new PointF(290, MaxY - 35));
                            }
                        }
                    }
                    break;
                case 4:
                    {
                        for (int i = 0; i < 4; i++)// iterate as number of clusters
                        {
                            m = ClusterSorted[i];
                            if (i == 0)
                            {
                                ClusteredImage.FillEllipse(RectBrush, 0, 0, w, h);
                                ClusteredImage.DrawEllipse(rectPen, 0, 0, w, h);
                                if (ClusterArray[m].numOfUsers1stInterests > 0.5)
                                {
                                    edgesperSTR = ClusterArray[m].interest1stpercent;
                                    edgesperSTR += "% " + ClusterArray[m].Interests1st;
                                }
                                else edgesperSTR = "No";
                                ClusteredImage.DrawString(((m + 1) + ") " + edgesperSTR), font1, Brush, new PointF(0, 0));
                            }
                            else if (i == 1)
                            {
                                ClusteredImage.FillEllipse(RectBrush, MaxX / 2 + 25, 0, w, h);
                                ClusteredImage.DrawEllipse(rectPen, MaxX / 2 + 25, 0, w, h);
                                if (ClusterArray[m].numOfUsers1stInterests > 0.5)
                                {
                                    edgesperSTR = ClusterArray[m].interest1stpercent;
                                    edgesperSTR += "% " + ClusterArray[m].Interests1st;
                                }
                                else edgesperSTR = "No";
                                ClusteredImage.DrawString(((m + 1) + ") " + edgesperSTR), font1, Brush, new PointF(MaxX / 2 + 25, 0));
                            }
                            else if (i == 2)
                            {
                                ClusteredImage.FillEllipse(RectBrush, 0, MaxY - 35, w, h);
                                ClusteredImage.DrawEllipse(rectPen, 0, MaxY - 35, w, h);
                                if (ClusterArray[m].numOfUsers1stInterests > 0.5)
                                {
                                    edgesperSTR = ClusterArray[m].interest1stpercent;
                                    edgesperSTR += "% " + ClusterArray[m].Interests1st;
                                }
                                else edgesperSTR = "No";
                                ClusteredImage.DrawString(((m + 1) + ") " + edgesperSTR), font1, Brush, new PointF(0, MaxY - 35));
                            }
                            else if (i == 3)
                            {
                                ClusteredImage.DrawEllipse(rectPen, MaxX / 2 + 25, MaxY - 35, w, h);
                                ClusteredImage.FillEllipse(RectBrush, MaxX / 2 + 25, MaxY - 35, w, h);
                                if (ClusterArray[m].numOfUsers1stInterests > 0.5)
                                {
                                    edgesperSTR = ClusterArray[m].interest1stpercent;
                                    edgesperSTR += "% " + ClusterArray[m].Interests1st;
                                }
                                else edgesperSTR = "No";
                                ClusteredImage.DrawString(((m + 1) + ") " + edgesperSTR), font1, Brush, new PointF(MaxX / 2 + 25, MaxY - 35));
                            }

                        }
                    }
                    break;
                case 5:
                    {
                        for (int i = 0; i < 5; i++)// iterate as number of clusters
                        {
                            m = ClusterSorted[i];
                            if (i == 0)
                            {
                                y = 0; x = 0;
                                ClusteredImage.DrawEllipse(rectPen, x, y, w, h);
                                ClusteredImage.FillEllipse(RectBrush, x, y, w, h);
                                if (ClusterArray[m].numOfUsers1stInterests > 0.5)
                                {
                                    edgesperSTR = ClusterArray[m].interest1stpercent;
                                    edgesperSTR += "% " + ClusterArray[m].Interests1st;
                                }
                                else edgesperSTR = "No";
                                ClusteredImage.DrawString(((m + 1) + ") " + edgesperSTR), font1, Brush, new PointF(x, y));
                            }
                            else if (i == 1)
                            {
                                y = 0; x = MaxX / 2 + 65;
                                ClusteredImage.DrawEllipse(rectPen, x, y, w, h);
                                ClusteredImage.FillEllipse(RectBrush, x, y, w, h);
                                if (ClusterArray[m].numOfUsers1stInterests > 0.5)
                                {
                                    edgesperSTR = ClusterArray[m].interest1stpercent;
                                    edgesperSTR += "% " + ClusterArray[m].Interests1st;
                                }
                                else edgesperSTR = "No";
                                ClusteredImage.DrawString(((m + 1) + ") " + edgesperSTR), font1, Brush, new PointF(x, y));
                            }
                            else if (i == 2)
                            {
                                y = MaxY / 2 + 45; x = 0;
                                ClusteredImage.DrawEllipse(rectPen, x, y, w, h);
                                ClusteredImage.FillEllipse(RectBrush, x, y, w, h);
                                if (ClusterArray[m].numOfUsers1stInterests > 0.5)
                                {
                                    edgesperSTR = ClusterArray[m].interest1stpercent;
                                    edgesperSTR += "% " + ClusterArray[m].Interests1st;
                                }
                                else edgesperSTR = "No";
                                ClusteredImage.DrawString(((m + 1) + ") " + edgesperSTR), font1, Brush, new PointF(x, y));
                            }
                            else if (i == 3)
                            {
                                y = MaxY / 2 + 65; x = MaxX / 2 + 70;
                                ClusteredImage.DrawEllipse(rectPen, x, y, w, h);
                                ClusteredImage.FillEllipse(RectBrush, x, y, w, h);
                                if (ClusterArray[m].numOfUsers1stInterests > 0.5)
                                {
                                    edgesperSTR = ClusterArray[m].interest1stpercent;
                                    edgesperSTR += "% " + ClusterArray[m].Interests1st;
                                }
                                else edgesperSTR = "No";
                                ClusteredImage.DrawString(((m + 1) + ") " + edgesperSTR), font1, Brush, new PointF(x, y));
                            }
                            else if (i == 4)
                            {
                                y = MaxY / 2 - 85; x = MaxX / 2 - 65;
                                ClusteredImage.DrawEllipse(rectPen, x, y, w, h);
                                ClusteredImage.FillEllipse(RectBrush, x, y, w, h);
                                if (ClusterArray[m].numOfUsers1stInterests > 0.5)
                                {
                                    edgesperSTR = ClusterArray[m].interest1stpercent;
                                    edgesperSTR += "% " + ClusterArray[m].Interests1st;
                                }
                                else edgesperSTR = "No";
                                ClusteredImage.DrawString(((m + 1) + ") " + edgesperSTR), font1, Brush, new PointF(x, y));
                            }
                        }
                    }
                    break;
                case 6:
                    {
                        for (int i = 0; i < 6; i++)// iterate as number of clusters
                        {
                            m = ClusterSorted[i];
                            if (i == 0)
                            {
                                x = 0; y = 0;
                                ClusteredImage.DrawEllipse(rectPen, x, y, w, h);
                                ClusteredImage.FillEllipse(RectBrush, x, y, w, h);
                                if (ClusterArray[m].numOfUsers1stInterests > 0.5)
                                {
                                    edgesperSTR = ClusterArray[m].interest1stpercent;
                                    edgesperSTR += "% " + ClusterArray[m].Interests1st;
                                }
                                else edgesperSTR = "No";
                                ClusteredImage.DrawString(((m + 1) + ") " + edgesperSTR), font1, Brush, new PointF(x, y));
                            }
                            else if (i == 1)
                            {
                                x = MaxX / 2 + 35; y = 0;
                                ClusteredImage.DrawEllipse(rectPen, x, y, w, h);
                                ClusteredImage.FillEllipse(RectBrush, x, y, w, h);
                                if (ClusterArray[m].numOfUsers1stInterests > 0.5)
                                {
                                    edgesperSTR = ClusterArray[m].interest1stpercent;
                                    edgesperSTR += "% " + ClusterArray[m].Interests1st;
                                }
                                else edgesperSTR = "No";
                                ClusteredImage.DrawString(((m + 1) + ") " + edgesperSTR), font1, Brush, new PointF(x, y));
                            }
                            else if (i == 2)
                            {
                                x = 0; y = MaxY / 3 + 25;
                                ClusteredImage.DrawEllipse(rectPen, x, y, w, h);
                                ClusteredImage.FillEllipse(RectBrush, x, y, w, h);
                                if (ClusterArray[m].numOfUsers1stInterests > 0.5)
                                {
                                    edgesperSTR = ClusterArray[m].interest1stpercent;
                                    edgesperSTR += "% " + ClusterArray[m].Interests1st;
                                }
                                else edgesperSTR = "No";
                                ClusteredImage.DrawString(((m + 1) + ") " + edgesperSTR), font1, Brush, new PointF(x, y));
                            }
                            else if (i == 3)
                            {
                                x = MaxX / 2 + 35; y = MaxY / 3 + 25;
                                ClusteredImage.DrawEllipse(rectPen, x, y, w, h);
                                ClusteredImage.FillEllipse(RectBrush, x, y, w, h);
                                if (ClusterArray[m].numOfUsers1stInterests > 0.5)
                                {
                                    edgesperSTR = ClusterArray[m].interest1stpercent;
                                    edgesperSTR += "% " + ClusterArray[m].Interests1st;
                                }
                                else edgesperSTR = "No";
                                ClusteredImage.DrawString(((m + 1) + ") " + edgesperSTR), font1, Brush, new PointF(x, y));
                            }
                            else if (i == 4)
                            {
                                x = 0; y = 2 * (MaxY / 3) + 25;
                                ClusteredImage.DrawEllipse(rectPen, x, y, w, h);
                                ClusteredImage.FillEllipse(RectBrush, x, y, w, h);
                                if (ClusterArray[m].numOfUsers1stInterests > 0.5)
                                {
                                    edgesperSTR = ClusterArray[m].interest1stpercent;
                                    edgesperSTR += "% " + ClusterArray[m].Interests1st;
                                }
                                else edgesperSTR = "No";
                                ClusteredImage.DrawString(((m + 1) + ") " + edgesperSTR), font1, Brush, new PointF(x, y));
                            }
                            else if (i == 5)
                            {
                                x = MaxX / 2 + 35; y = 2 * (MaxY / 3) + 35;
                                ClusteredImage.DrawEllipse(rectPen, x, y, w, h);
                                ClusteredImage.FillEllipse(RectBrush, x, y, w, h);
                                if (ClusterArray[m].numOfUsers1stInterests > 0.5)
                                {
                                    edgesperSTR = ClusterArray[m].interest1stpercent;
                                    edgesperSTR += "% " + ClusterArray[m].Interests1st;
                                }
                                else edgesperSTR = "No";
                                ClusteredImage.DrawString(((m + 1) + ") " + edgesperSTR), font1, Brush, new PointF(x, y));
                            }
                        }
                    }
                    break;
                case 7:
                    {
                        for (int i = 0; i < 7; i++)// iterate as number of clusters
                        {
                            m = ClusterSorted[i];
                            if (i == 0)
                            {
                                x = 0; y = 0;
                                ClusteredImage.DrawEllipse(rectPen, x, y, w, h);
                                ClusteredImage.FillEllipse(RectBrush, x, y, w, h);
                                if (ClusterArray[m].numOfUsers1stInterests > 0.5)
                                {
                                    edgesperSTR = ClusterArray[m].interest1stpercent;
                                    edgesperSTR += "% " + ClusterArray[m].Interests1st;
                                }
                                else edgesperSTR = "No";
                                ClusteredImage.DrawString(((m + 1) + ") " + edgesperSTR), font1, Brush, new PointF(x, y));
                            }
                            else if (i == 1)
                            {
                                x = MaxX / 2 + 125; y = 0;
                                ClusteredImage.DrawEllipse(rectPen, x, y, w, h);
                                ClusteredImage.FillEllipse(RectBrush, x, y, w, h);
                                if (ClusterArray[m].numOfUsers1stInterests > 0.5)
                                {
                                    edgesperSTR = ClusterArray[m].interest1stpercent;
                                    edgesperSTR += "% " + ClusterArray[m].Interests1st;
                                }
                                else edgesperSTR = "No";
                                ClusteredImage.DrawString(((m + 1) + ") " + edgesperSTR), font1, Brush, new PointF(x, y));
                            }
                            else if (i == 2)
                            {
                                x = 0; y = MaxY / 3 + 35;
                                ClusteredImage.DrawEllipse(rectPen, x, y, w, h);
                                ClusteredImage.FillEllipse(RectBrush, x, y, w, h);
                                if (ClusterArray[m].numOfUsers1stInterests > 0.5)
                                {
                                    edgesperSTR = ClusterArray[m].interest1stpercent;
                                    edgesperSTR += "% " + ClusterArray[m].Interests1st;
                                }
                                else edgesperSTR = "No";
                                ClusteredImage.DrawString(((m + 1) + ") " + edgesperSTR), font1, Brush, new PointF(x, y));
                            }
                            else if (i == 3)
                            {
                                x = MaxX / 2 + 125; y = MaxY / 3 + 35;
                                ClusteredImage.DrawEllipse(rectPen, x, y, w, h);
                                ClusteredImage.FillEllipse(RectBrush, x, y, w, h);
                                if (ClusterArray[m].numOfUsers1stInterests > 0.5)
                                {
                                    edgesperSTR = ClusterArray[m].interest1stpercent;
                                    edgesperSTR += "% " + ClusterArray[m].Interests1st;
                                }
                                else edgesperSTR = "No";
                                ClusteredImage.DrawString(((m + 1) + ") " + edgesperSTR), font1, Brush, new PointF(x, y));
                            }
                            else if (i == 4)
                            {
                                x = 0; y = 2 * (MaxY / 3) + 25;
                                ClusteredImage.DrawEllipse(rectPen, x, y, w, h);
                                ClusteredImage.FillEllipse(RectBrush, x, y, w, h);
                                if (ClusterArray[m].numOfUsers1stInterests > 0.5)
                                {
                                    edgesperSTR = ClusterArray[m].interest1stpercent;
                                    edgesperSTR += "% " + ClusterArray[m].Interests1st;
                                }
                                else edgesperSTR = "No";
                                ClusteredImage.DrawString(((m + 1) + ") " + edgesperSTR), font1, Brush, new PointF(x, y));
                            }
                            else if (i == 5)
                            {
                                x = MaxX / 2 + 125; y = 2 * (MaxY / 3) + 25;
                                ClusteredImage.DrawEllipse(rectPen, x, y, w, h);
                                ClusteredImage.FillEllipse(RectBrush, x, y, w, h);
                                if (ClusterArray[m].numOfUsers1stInterests > 0.5)
                                {
                                    edgesperSTR = ClusterArray[m].interest1stpercent;
                                    edgesperSTR += "% " + ClusterArray[m].Interests1st;
                                }
                                else edgesperSTR = "No";
                                ClusteredImage.DrawString(((m + 1) + ") " + edgesperSTR), font1, Brush, new PointF(x, y));
                            }
                            else if (i == 6)
                            {
                                x = MaxX / 2 - 120; y = 0;
                                ClusteredImage.DrawEllipse(rectPen, x, y, w, h);
                                ClusteredImage.FillEllipse(RectBrush, x, y, w, h);
                                if (ClusterArray[m].numOfUsers1stInterests > 0.5)
                                {
                                    edgesperSTR = ClusterArray[m].interest1stpercent;
                                    edgesperSTR += "% " + ClusterArray[m].Interests1st;
                                }
                                else edgesperSTR = "No";
                                ClusteredImage.DrawString(((m + 1) + ") " + edgesperSTR), font1, Brush, new PointF(x, y));
                            }
                        }
                    }
                    break;
                case 8:
                    {
                        for (int i = 0; i < 8; i++)// iterate as number of clusters
                        {
                            m = ClusterSorted[i];
                            if (i == 0)
                            {
                                x = 0; y = 0;
                                ClusteredImage.DrawEllipse(rectPen, x, y, w, h);
                                ClusteredImage.FillEllipse(RectBrush, x, y, w, h);
                                if (ClusterArray[m].numOfUsers1stInterests > 0.5)
                                {
                                    edgesperSTR = ClusterArray[m].interest1stpercent;
                                    edgesperSTR += "% " + ClusterArray[m].Interests1st;
                                }
                                else edgesperSTR = "No";
                                ClusteredImage.DrawString(((m + 1) + ") " + edgesperSTR), font1, Brush, new PointF(x, y));
                            }
                            else if (i == 1)
                            {
                                x = MaxX / 2 + 125; y = 0;
                                ClusteredImage.DrawEllipse(rectPen, x, y, w, h);
                                ClusteredImage.FillEllipse(RectBrush, x, y, w, h);
                                if (ClusterArray[m].numOfUsers1stInterests > 0.5)
                                {
                                    edgesperSTR = ClusterArray[m].interest1stpercent;
                                    edgesperSTR += "% " + ClusterArray[m].Interests1st;
                                }
                                else edgesperSTR = "No";
                                ClusteredImage.DrawString(((m + 1) + ") " + edgesperSTR), font1, Brush, new PointF(x, y));
                            }
                            else if (i == 2)
                            {
                                x = 0; y = MaxY / 3 + 35;
                                ClusteredImage.DrawEllipse(rectPen, x, y, w, h);
                                ClusteredImage.FillEllipse(RectBrush, x, y, w, h);
                                if (ClusterArray[m].numOfUsers1stInterests > 0.5)
                                {
                                    edgesperSTR = ClusterArray[m].interest1stpercent;
                                    edgesperSTR += "% " + ClusterArray[m].Interests1st;
                                }
                                else edgesperSTR = "No";
                                ClusteredImage.DrawString(((m + 1) + ") " + edgesperSTR), font1, Brush, new PointF(x, y));
                            }
                            else if (i == 3)
                            {
                                x = MaxX / 2 + 125; y = MaxY / 3 + 35;
                                ClusteredImage.DrawEllipse(rectPen, x, y, w, h);
                                ClusteredImage.FillEllipse(RectBrush, x, y, w, h);
                                if (ClusterArray[m].numOfUsers1stInterests > 0.5)
                                {
                                    edgesperSTR = ClusterArray[m].interest1stpercent;
                                    edgesperSTR += "% " + ClusterArray[m].Interests1st;
                                }
                                else edgesperSTR = "No";
                                ClusteredImage.DrawString(((m + 1) + ") " + edgesperSTR), font1, Brush, new PointF(x, y));
                            }
                            else if (i == 4)
                            {
                                x = 0; y = 2 * (MaxY / 3) + 25;
                                ClusteredImage.DrawEllipse(rectPen, x, y, w, h);
                                ClusteredImage.FillEllipse(RectBrush, x, y, w, h);
                                if (ClusterArray[m].numOfUsers1stInterests > 0.5)
                                {
                                    edgesperSTR = ClusterArray[m].interest1stpercent;
                                    edgesperSTR += "% " + ClusterArray[m].Interests1st;
                                }
                                else edgesperSTR = "No";
                                ClusteredImage.DrawString(((m + 1) + ") " + edgesperSTR), font1, Brush, new PointF(x, y));
                            }
                            else if (i == 5)
                            {
                                x = MaxX / 2 + 125; y = 2 * (MaxY / 3) + 25;
                                ClusteredImage.DrawEllipse(rectPen, x, y, w, h);
                                ClusteredImage.FillEllipse(RectBrush, x, y, w, h);
                                if (ClusterArray[m].numOfUsers1stInterests > 0.5)
                                {
                                    edgesperSTR = ClusterArray[m].interest1stpercent;
                                    edgesperSTR += "% " + ClusterArray[m].Interests1st;
                                }
                                else edgesperSTR = "No";
                                ClusteredImage.DrawString(((m + 1) + ") " + edgesperSTR), font1, Brush, new PointF(x, y));
                            }
                            else if (i == 6)
                            {
                                x = MaxX / 2 - 120; y = 0;
                                ClusteredImage.DrawEllipse(rectPen, x, y, w, h);
                                ClusteredImage.FillEllipse(RectBrush, x, y, w, h);
                                if (ClusterArray[m].numOfUsers1stInterests > 0.5)
                                {
                                    edgesperSTR = ClusterArray[m].interest1stpercent;
                                    edgesperSTR += "% " + ClusterArray[m].Interests1st;
                                }
                                else edgesperSTR = "No";
                                ClusteredImage.DrawString(((m + 1) + ") " + edgesperSTR), font1, Brush, new PointF(x, y));
                            }
                            else if (i == 7)
                            {
                                x = MaxX / 2 - 120; y = MaxY / 3 + 25;
                                ClusteredImage.DrawEllipse(rectPen, x, y, w, h);
                                ClusteredImage.FillEllipse(RectBrush, x, y, w, h);
                                if (ClusterArray[m].numOfUsers1stInterests > 0.5)
                                {
                                    edgesperSTR = ClusterArray[m].interest1stpercent;
                                    edgesperSTR += "% " + ClusterArray[m].Interests1st;
                                }
                                else edgesperSTR = "No";
                                ClusteredImage.DrawString(((m + 1) + ") " + edgesperSTR), font1, Brush, new PointF(x, y));
                            }
                        }
                    }
                    break;
                case 9:
                    {
                        for (int i = 0; i < 9; i++)// iterate as number of clusters
                        {
                            m = ClusterSorted[i];
                            if (i == 0)
                            {
                                x = 0; y = 0;
                                ClusteredImage.DrawEllipse(rectPen, x, y, w, h);
                                ClusteredImage.FillEllipse(RectBrush, x, y, w, h);
                                if (ClusterArray[m].numOfUsers1stInterests > 0.5)
                                {
                                    edgesperSTR = ClusterArray[m].interest1stpercent;
                                    edgesperSTR += "% " + ClusterArray[m].Interests1st;
                                }
                                else edgesperSTR = "No";
                                ClusteredImage.DrawString(((m + 1) + ") " + edgesperSTR), font1, Brush, new PointF(x, y));
                            }
                            else if (i == 1)
                            {
                                x = MaxX / 2 + 125; y = 0;
                                ClusteredImage.DrawEllipse(rectPen, x, y, w, h);
                                ClusteredImage.FillEllipse(RectBrush, x, y, w, h);
                                if (ClusterArray[m].numOfUsers1stInterests > 0.5)
                                {
                                    edgesperSTR = ClusterArray[m].interest1stpercent;
                                    edgesperSTR += "% " + ClusterArray[m].Interests1st;
                                }
                                else edgesperSTR = "No";
                                ClusteredImage.DrawString(((m + 1) + ") " + edgesperSTR), font1, Brush, new PointF(x, y));
                            }
                            else if (i == 2)
                            {
                                x = 0; y = MaxY / 3 + 35;
                                ClusteredImage.DrawEllipse(rectPen, x, y, w, h);
                                ClusteredImage.FillEllipse(RectBrush, x, y, w, h);
                                if (ClusterArray[m].numOfUsers1stInterests > 0.5)
                                {
                                    edgesperSTR = ClusterArray[m].interest1stpercent;
                                    edgesperSTR += "% " + ClusterArray[m].Interests1st;
                                }
                                else edgesperSTR = "No";
                                ClusteredImage.DrawString(((m + 1) + ") " + edgesperSTR), font1, Brush, new PointF(x, y));
                            }
                            else if (i == 3)
                            {
                                x = MaxX / 2 + 125; y = MaxY / 3 + 35;
                                ClusteredImage.DrawEllipse(rectPen, x, y, w, h);
                                ClusteredImage.FillEllipse(RectBrush, x, y, w, h);
                                if (ClusterArray[m].numOfUsers1stInterests > 0.5)
                                {
                                    edgesperSTR = ClusterArray[m].interest1stpercent;
                                    edgesperSTR += "% " + ClusterArray[m].Interests1st;
                                }
                                else edgesperSTR = "No";
                                ClusteredImage.DrawString(((m + 1) + ") " + edgesperSTR), font1, Brush, new PointF(x, y));
                            }
                            else if (i == 4)
                            {
                                x = 0; y = 2 * (MaxY / 3) + 25;
                                ClusteredImage.DrawEllipse(rectPen, x, y, w, h);
                                ClusteredImage.FillEllipse(RectBrush, x, y, w, h);
                                if (ClusterArray[m].numOfUsers1stInterests > 0.5)
                                {
                                    edgesperSTR = ClusterArray[m].interest1stpercent;
                                    edgesperSTR += "% " + ClusterArray[m].Interests1st;
                                }
                                else edgesperSTR = "No";
                                ClusteredImage.DrawString(((m + 1) + ") " + edgesperSTR), font1, Brush, new PointF(x, y));
                            }
                            else if (i == 5)
                            {
                                x = MaxX / 2 + 125; y = 2 * (MaxY / 3) + 25;
                                ClusteredImage.DrawEllipse(rectPen, x, y, w, h);
                                ClusteredImage.FillEllipse(RectBrush, x, y, w, h);
                                if (ClusterArray[m].numOfUsers1stInterests > 0.5)
                                {
                                    edgesperSTR = ClusterArray[m].interest1stpercent;
                                    edgesperSTR += "% " + ClusterArray[m].Interests1st;
                                }
                                else edgesperSTR = "No";
                                ClusteredImage.DrawString(((m + 1) + ") " + edgesperSTR), font1, Brush, new PointF(x, y));
                            }
                            else if (i == 6)
                            {
                                x = MaxX / 2 - 120; y = 0;
                                ClusteredImage.DrawEllipse(rectPen, x, y, w, h);
                                ClusteredImage.FillEllipse(RectBrush, x, y, w, h);
                                if (ClusterArray[m].numOfUsers1stInterests > 0.5)
                                {
                                    edgesperSTR = ClusterArray[m].interest1stpercent;
                                    edgesperSTR += "% " + ClusterArray[m].Interests1st;
                                }
                                else edgesperSTR = "No";
                                ClusteredImage.DrawString(((m + 1) + ") " + edgesperSTR), font1, Brush, new PointF(x, y));
                            }
                            else if (i == 7)
                            {
                                x = MaxX / 2 - 120; y = MaxY / 3 + 25;
                                ClusteredImage.DrawEllipse(rectPen, x, y, w, h);
                                ClusteredImage.FillEllipse(RectBrush, x, y, w, h);
                                if (ClusterArray[m].numOfUsers1stInterests > 0.5)
                                {
                                    edgesperSTR = ClusterArray[m].interest1stpercent;
                                    edgesperSTR += "% " + ClusterArray[m].Interests1st;
                                }
                                else edgesperSTR = "No";
                                ClusteredImage.DrawString(((m + 1) + ") " + edgesperSTR), font1, Brush, new PointF(x, y));
                            }
                            else if (i == 8)
                            {
                                x = MaxX / 2 - 120; y = 2 * (MaxY / 3) + 25;
                                ClusteredImage.DrawEllipse(rectPen, x, y, w, h);
                                ClusteredImage.FillEllipse(RectBrush, x, y, w, h);
                                if (ClusterArray[m].numOfUsers1stInterests > 0.5)
                                {
                                    edgesperSTR = ClusterArray[m].interest1stpercent;
                                    edgesperSTR += "% " + ClusterArray[m].Interests1st;
                                }
                                else edgesperSTR = "No";
                                ClusteredImage.DrawString(((m + 1) + ") " + edgesperSTR), font1, Brush, new PointF(x, y));
                            }
                        }
                    }
                    break;
            }
        }



      
        public void calcPositionOfNodes(int[] ClusterSorted)
        {              
            Point temp=new Point();
            int MaxX = Main_Window.imgXClusteredGraph, MaxY = Main_Window.imgYClusteredGraph;
            MaxX -= 35; MaxY -= 35;
            int tempLength = ClusterArrayActualLength;
            if (tempLength > 9)
                tempLength = 9;  
            int m=-1;  
            switch (tempLength)
            {
                case 1:
                    {
                        for (int j = 0; j < ClusterArray[0].numOfNodes; j++)// iterate as number of node at each cluster
                        {
                            temp.X = rand.Next(MaxX);
                            temp.Y = rand.Next(MaxY);
                            kernalCoard[ClusterArray[0].nodesInCluster[j]].X = temp.X;// ClusterArray[0].nodesInCluster[j] = the index of the node
                            kernalCoard[ClusterArray[0].nodesInCluster[j]].Y = temp.Y;
                        }
                    }
                    break;
                case 2:
                    {
                        for (int i = 0; i < 2; i++)// iterate as number of clusters
                        {
                            m = ClusterSorted[i];
                            for (int j = 0; j < ClusterArray[m].numOfNodes; j++)// iterate as number of node at each cluster
                            {
                                if (i == 0)
                                {                                    
                                        temp.X = rand.Next(MaxX / 2 - 50);
                                        temp.Y = rand.Next(100, MaxY - 100);                                    
                                }
                                if (i == 1)
                                {                                    
                                        temp.X = rand.Next(MaxX / 2 + 50, MaxX);
                                        temp.Y = rand.Next(100, MaxY - 100);
                                }
                                kernalCoard[ClusterArray[m].nodesInCluster[j]].X = temp.X;// ClusterArray[m].nodesInCluster[j] = the index of the node
                                kernalCoard[ClusterArray[m].nodesInCluster[j]].Y = temp.Y;
                            }
                        }
                    }
                    break;
                case 3:
                    {
                        for (int i = 0; i < 3; i++)// iterate as number of clusters
                        {
                            m = ClusterSorted[i];
                            for (int j = 0; j < ClusterArray[m].numOfNodes; j++)// iterate as number of node at each cluster
                            {
                                if (i == 0)
                                {
                                        temp.X = rand.Next(0, 300);
                                        temp.Y = rand.Next(0, 230);
                                }
                                if (i == 1)
                                {
                                        temp.X = rand.Next(425, MaxX);
                                        temp.Y = rand.Next(0, 230);
                                }
                                if (i == 2)
                                {
                                        temp.X = rand.Next(175, 475);
                                        temp.Y = rand.Next(290, MaxY);
                                }
                                kernalCoard[ClusterArray[m].nodesInCluster[j]].X = temp.X;// ClusterArray[m].nodesInCluster[j] = the index of the node
                                kernalCoard[ClusterArray[m].nodesInCluster[j]].Y = temp.Y;
                            }
                        }
                    }
                    break;
                case 4:
                    {
                        for (int i = 0; i < 4; i++)// iterate as number of clusters
                        {
                            m = ClusterSorted[i];
                            for (int j = 0; j < ClusterArray[m].numOfNodes; j++)// iterate as number of node at each cluster
                            {
                                if (i == 0)
                                {
                                        temp.X = rand.Next(MaxX / 2 - 50);
                                        temp.Y = rand.Next(0, MaxY / 2 - 30);
                                }
                                if (i == 1)
                                {
                                        temp.X = rand.Next(MaxX / 2 + 50, MaxX);
                                        temp.Y = rand.Next(0, MaxY / 2 - 30);
                                }
                                if (i == 2)
                                {
                                        temp.X = rand.Next(MaxX / 2 - 50);
                                        temp.Y = rand.Next(MaxY / 2 + 30, MaxY);
                                }
                                if (i == 3)
                                {
                                        temp.X = rand.Next(MaxX / 2 + 50, MaxX);
                                        temp.Y = rand.Next(MaxY / 2 + 30, MaxY);
                                }
                                kernalCoard[ClusterArray[m].nodesInCluster[j]].X = temp.X;// ClusterArray[m].nodesInCluster[j] = the index of the node
                                kernalCoard[ClusterArray[m].nodesInCluster[j]].Y = temp.Y;
                            }
                        }
                    }
                    break;
                case 5:
                    {
                        for (int i = 0; i < 5; i++)// iterate as number of clusters
                        {
                            m = ClusterSorted[i];
                            for (int j = 0; j < ClusterArray[m].numOfNodes; j++)// iterate as number of node at each cluster
                            {                                
                                if (i == 0)
                                {
                                        temp.X = rand.Next(MaxX / 2 - 90);
                                        temp.Y = rand.Next(0, MaxY / 2 - 60);
                                }
                                if (i == 1)
                                {
                                        temp.X = rand.Next(MaxX / 2 + 90, MaxX);
                                        temp.Y = rand.Next(0, MaxY / 2 - 60);
                                }
                                if (i == 2)
                                {
                                        temp.X = rand.Next(MaxX / 2 - 80);
                                        temp.Y = rand.Next(MaxY / 2 + 60, MaxY);
                                }
                                if (i == 3)
                                {
                                        temp.X = rand.Next(MaxX / 2 + 80, MaxX);
                                        temp.Y = rand.Next(MaxY / 2 + 60, MaxY);
                                }
                                if (i == 4)
                                {
                                        temp.X = rand.Next(MaxX / 2 - 90, MaxX / 2 + 90);
                                        temp.Y = rand.Next(MaxY / 2 - 60, MaxY / 2 + 60);
                                }

                                kernalCoard[ClusterArray[m].nodesInCluster[j]].X = temp.X;// ClusterArray[m].nodesInCluster[j] = the index of the node
                                kernalCoard[ClusterArray[m].nodesInCluster[j]].Y = temp.Y;
                            }
                        }
                    }
                    break;
                case 6:
                    {
                        for (int i = 0; i < 6; i++)// iterate as number of clusters
                        {
                            m = ClusterSorted[i];
                            for (int j = 0; j < ClusterArray[m].numOfNodes; j++)// iterate as number of node at each cluster
                            {
                                if (i == 0)
                                {
                                        temp.X = rand.Next(MaxX / 2 - 60);
                                        temp.Y = rand.Next(0, MaxY / 3 - 40);
                                }
                                if (i == 1)
                                {
                                        temp.X = rand.Next(MaxX / 2 + 60, MaxX);
                                        temp.Y = rand.Next(0, MaxY / 3 - 40);
                                }
                                if (i == 2)
                                {
                                        temp.X = rand.Next(MaxX / 2 - 60);
                                        temp.Y = rand.Next(MaxY / 3 + 40, 2 * (MaxY / 3) - 40);
                                }
                                if (i == 3)
                                {
                                        temp.X = rand.Next(MaxX / 2 + 60, MaxX);
                                        temp.Y = rand.Next(MaxY / 3 + 40, 2 * (MaxY / 3) - 40);
                                }
                                if (i == 4)
                                {
                                        temp.X = rand.Next(MaxX / 2 - 60);
                                        temp.Y = rand.Next(2 * (MaxY / 3) + 40, MaxY);
                                }
                                if (i == 5)
                                {
                                        temp.X = rand.Next(MaxX / 2 + 60, MaxX);
                                        temp.Y = rand.Next(2 * (MaxY / 3) + 40, MaxY);
                                }
                                kernalCoard[ClusterArray[m].nodesInCluster[j]].X = temp.X;// ClusterArray[m].nodesInCluster[j] = the index of the node
                                kernalCoard[ClusterArray[m].nodesInCluster[j]].Y = temp.Y;
                            }
                        }
                    }
                    break;
                case 7:
                    {
                        for (int i = 0; i < 7; i++)// iterate as number of clusters
                        {
                            m = ClusterSorted[i];
                            for (int j = 0; j < ClusterArray[m].numOfNodes; j++)// iterate as number of node at each cluster
                            {
                                if (i == 0)
                                {
                                        temp.X = rand.Next(MaxX / 2 - 150);
                                        temp.Y = rand.Next(0, MaxY / 3 - 40);
                                }
                                if (i == 1)
                                {
                                        temp.X = rand.Next(MaxX / 2 + 150, MaxX);
                                        temp.Y = rand.Next(0, MaxY / 3 - 40);
                                }
                                if (i == 2)
                                {
                                        temp.X = rand.Next(MaxX / 2 - 150);
                                        temp.Y = rand.Next(MaxY / 3 + 40, 2 * (MaxY / 3) - 40);
                                }
                                if (i == 3)
                                {
                                        temp.X = rand.Next(MaxX / 2 + 150, MaxX);
                                        temp.Y = rand.Next(MaxY / 3 + 40, 2 * (MaxY / 3) - 40);
                                }
                                if (i == 4)
                                {
                                        temp.X = rand.Next(MaxX / 2 - 150);
                                        temp.Y = rand.Next(2 * (MaxY / 3) + 40, MaxY);
                                }
                                if (i == 5)
                                {
                                        temp.X = rand.Next(MaxX / 2 + 150, MaxX);
                                        temp.Y = rand.Next(2 * (MaxY / 3) + 40, MaxY);
                                }
                                if (i == 6)
                                {
                                        temp.X = rand.Next(MaxX / 2 - 100, MaxX / 2 + 100);
                                        temp.Y = rand.Next(0, MaxY / 3 - 40);
                                }

                                kernalCoard[ClusterArray[m].nodesInCluster[j]].X = temp.X;// ClusterArray[m].nodesInCluster[j] = the index of the node
                                kernalCoard[ClusterArray[m].nodesInCluster[j]].Y = temp.Y;
                            }
                        }
                    }
                    break;
                case 8:
                    {
                        for (int i = 0; i < 8; i++)// iterate as number of clusters
                        {
                            m = ClusterSorted[i];
                            for (int j = 0; j < ClusterArray[m].numOfNodes; j++)// iterate as number of node at each cluster
                            {
                                if (i == 0)
                                {
                                        temp.X = rand.Next(MaxX / 2 - 150);
                                        temp.Y = rand.Next(0, MaxY / 3 - 40);
                                }
                                if (i == 1)
                                {
                                        temp.X = rand.Next(MaxX / 2 + 150, MaxX);
                                        temp.Y = rand.Next(0, MaxY / 3 - 40);
                                }
                                if (i == 2)
                                {
                                        temp.X = rand.Next(MaxX / 2 - 150);
                                        temp.Y = rand.Next(MaxY / 3 + 40, 2 * (MaxY / 3) - 40);
                                }
                                if (i == 3)
                                {
                                        temp.X = rand.Next(MaxX / 2 + 150, MaxX);
                                        temp.Y = rand.Next(MaxY / 3 + 40, 2 * (MaxY / 3) - 40);
                                }
                                if (i == 4)
                                {
                                        temp.X = rand.Next(MaxX / 2 - 150);
                                        temp.Y = rand.Next(2 * (MaxY / 3) + 40, MaxY);
                                }
                                if (i == 5)
                                {
                                        temp.X = rand.Next(MaxX / 2 + 150, MaxX);
                                        temp.Y = rand.Next(2 * (MaxY / 3) + 40, MaxY);
                                }
                                if (i == 6)
                                {
                                        temp.X = rand.Next(MaxX / 2 - 100, MaxX / 2 + 100);
                                        temp.Y = rand.Next(0, MaxY / 3 - 40);
                                }
                                if (i == 7)
                                {
                                        temp.X = rand.Next(MaxX / 2 - 100, MaxX / 2 + 100);
                                        temp.Y = rand.Next(MaxY / 3 + 40, 2 * (MaxY / 3) - 40);
                                }
                                kernalCoard[ClusterArray[m].nodesInCluster[j]].X = temp.X;// ClusterArray[m].nodesInCluster[j] = the index of the node
                                kernalCoard[ClusterArray[m].nodesInCluster[j]].Y = temp.Y;
                            }
                        }
                    }
                    break;
                case 9:
                    {
                        for (int i = 0; i < 9; i++)// iterate as number of clusters
                        {
                            m = ClusterSorted[i];
                            for (int j = 0; j < ClusterArray[m].numOfNodes; j++)// iterate as number of node at each cluster
                            {                                
                                if (i == 0)
                                {
                                        temp.X = rand.Next(MaxX / 2 - 150);
                                        temp.Y = rand.Next(0, MaxY / 3 - 40);
                                }
                                if (i == 1)
                                {
                                        temp.X = rand.Next(MaxX / 2 + 150, MaxX);
                                        temp.Y = rand.Next(0, MaxY / 3 - 40);
                                }
                                if (i == 2)
                                {
                                        temp.X = rand.Next(MaxX / 2 - 150);
                                        temp.Y = rand.Next(MaxY / 3 + 40, 2 * (MaxY / 3) - 40);
                                }
                                if (i == 3)
                                {
                                        temp.X = rand.Next(MaxX / 2 + 150, MaxX);
                                        temp.Y = rand.Next(MaxY / 3 + 40, 2 * (MaxY / 3) - 40);
                                }
                                if (i == 4)
                                {
                                        temp.X = rand.Next(MaxX / 2 - 150);
                                        temp.Y = rand.Next(2 * (MaxY / 3) + 40, MaxY);
                                }
                                if (i == 5)
                                {
                                        temp.X = rand.Next(MaxX / 2 + 150, MaxX);
                                        temp.Y = rand.Next(2 * (MaxY / 3) + 40, MaxY);
                                }
                                if (i == 6)
                                {
                                        temp.X = rand.Next(MaxX / 2 - 100, MaxX / 2 + 100);
                                        temp.Y = rand.Next(0, MaxY / 3 - 40);
                                }
                                if (i == 7)
                                {
                                        temp.X = rand.Next(MaxX / 2 - 100, MaxX / 2 + 100);
                                        temp.Y = rand.Next(MaxY / 3 + 40, 2 * (MaxY / 3) - 40);
                                }
                                if (i == 8)
                                {
                                        temp.X = rand.Next(MaxX / 2 - 100, MaxX / 2 + 100);
                                        temp.Y = rand.Next(2 * (MaxY / 3) + 40, MaxY);
                                }
                                kernalCoard[ClusterArray[m].nodesInCluster[j]].X = temp.X;// ClusterArray[m].nodesInCluster[j] = the index of the node
                                kernalCoard[ClusterArray[m].nodesInCluster[j]].Y = temp.Y;
                            }
                        }
                    }
                    break;
            }
        }

        
        public void RunKernelKMeans(int updatedNumOfClusters ,int testFlag)
        {
            Random ranCluster = new Random();
            double bestResult=100,tempRes;
            this.numOfClusters = updatedNumOfClusters;
            int temp_2 = net.numOfNodesKernel_new-net.numOfNodesKernel_old;
            Main_Window.NodesInKernel = net.numOfNodesKernel_new;
            if (testFlag == 1 && net.numOfNodesKernel_old == 0)
                InitialClusterForNodes_Test();
            else
                if (testFlag == 0 && net.numOfNodesKernel_old ==0)
                    InitialClusterForNodes();
                     
            if (this.kernelMatrix.Data.GetLength(0)!= net.numOfNodesKernel_new)
                                 calcKernekMatrix(this.m_kMatrix);
               for (int i = 0; i < net.numOfNodesKernel_new; i++)
                {
                    for (int k = 0; k < this.numOfClusters; k++)
                    {
                        
                        tempRes = this.kernelMatrix.Data[i,i] - CalcSum1(k, i) + CalcSum2(k,i);
                        if (tempRes < bestResult)
                        {
                            bestResult = tempRes;
                            bestCluster[i] = k;
                        }
                    }
                    bestResult = 100;
                    if (this.ClusterNode[i] != bestCluster[i] )
                    {
                       if (this.ClusterNode[i] != -1)
                            this.ClusterArray[this.ClusterNode[i]].deletetNode(i);
                        this.ClusterArray[bestCluster[i]].insertNode(i);
                        this.ClusterNode[i] = bestCluster[i];
                    }  
            }        
        }

        public double CalcSum1(int indexCluster ,int indexNode)
        {
              double Res=0 , temp =0 , SumOfWeight =0;
              for (int i = 0; i < this.ClusterArray[indexCluster].numOfNodes; i++)
              {
                  if (indexNode != ClusterArray[indexCluster].nodesInCluster[i])
                  {
                      if (this.ClusterArray[indexCluster].nodesInCluster[i] != -1)
                      {
                          temp = this.kernelMatrix[indexNode, this.ClusterArray[indexCluster].nodesInCluster[i]] * this.weightOfNode[this.ClusterArray[indexCluster].nodesInCluster[i]];
                          Res += temp;
                          SumOfWeight += this.weightOfNode[this.ClusterArray[indexCluster].nodesInCluster[i]];
                      }
                  }
              }
              return (2 * Res / SumOfWeight);
        }

        public double CalcSum2 (int indexCluster, int indexNode)
        {
            double Res = 0, temp = 0,  SumOfWeight=0;

            for (int i = 0; i < this.ClusterArray[indexCluster].numOfNodes; i++)
            {
                   
                for (int j = i + 1; j < this.ClusterArray[indexCluster].numOfNodes; j++)
                {
                    if ((((this.ClusterArray[indexCluster].nodesInCluster[i])) != (indexNode)) && (((this.ClusterArray[indexCluster].nodesInCluster[j])) != (indexNode)))
                    
                    {
                        if (this.ClusterArray[indexCluster].nodesInCluster[i] != -1 && this.ClusterArray[indexCluster].nodesInCluster[j]!=-1)
                        {
                        temp = this.weightOfNode[this.ClusterArray[indexCluster].nodesInCluster[i]] * this.weightOfNode[this.ClusterArray[indexCluster].nodesInCluster[j]];
                        temp *= this.kernelMatrix[this.ClusterArray[indexCluster].nodesInCluster[i], this.ClusterArray[indexCluster].nodesInCluster[j]];
                        Res += temp;
                        }
                    }
                }
                if (this.ClusterArray[indexCluster].nodesInCluster[i] != -1)
                SumOfWeight += this.weightOfNode[this.ClusterArray[indexCluster].nodesInCluster[i]];
            }
            return (Res /( SumOfWeight * SumOfWeight));
        }

        public void calcKernekMatrix(int choosenMatrix)
        {
            switch (choosenMatrix)
               { 
                case 1:
                       kernelMatrix = this.UnitMatrix + net.adjacnyMatrix;
                       for (int i = 0; i < net.numOfNodesKernel_new; i++)
                        this.weightOfNode[i] = 1;                
                       break;
                case 2:
                     for (int i = 0; i < net.numOfNodesKernel_new; i++)                   
                       for (int j = 0; j < net.numOfNodesKernel_new; j++)
                          this.D.Data[i, i] = this.D.Data[i, i]+ net.adjacnyMatrix.Data[i, j];   
                    kernelMatrix = (this.UnitMatrix - this.D) + net.adjacnyMatrix;
                       for (int i = 0; i < net.numOfNodesKernel_new; i++)
                           this.weightOfNode[i] = 1;
                       break;
                case 3:
                       for (int i = 0; i < net.numOfNodesKernel_new; i++)
                       {
                           for (int j = 0; j < net.numOfNodesKernel_new; j++)
                           {
                               this.D.Data[i, i] += net.adjacnyMatrix.Data[i, j];
                           }
                           this.weightOfNode[i] = (int)this.D.Data[i, i];
                       }                  
                       Matrix temp = new Matrix(net.adjacnyMatrix.Data.GetLength(1));
                       temp = this.DInverse;
                       Main_Window.NodesInKernel = this.numOfNodesKernel;
                       this.DInverse = this.D.Inverse();
                       if (this.DInverse.Data.GetLength(0)==0 )
                       {
                           this.ErrorFlag = 1;
                           break;
                       }
                       else
                       {
                           for (int i = 0; i < net.numOfNodesKernel_new; i++)
                           {
                               this.SigmaDInverse.Data[i, i] = this.DInverse.Data[i, i] * this.Sigma;
                           }
                           kernelMatrix = this.SigmaDInverse + (this.DInverse * net.adjacnyMatrix) * this.DInverse;
                           break;
                       }
               }
        }

        public void InitialClusterForNodes()
        {
            for (int i = net.numOfNodesKernel_old; i < net.numOfNodesKernel_new; i++) // set each node to a cluster
            {
                switch (i % numOfClusters)
                {
                    case 0:
                        if (this.ClusterNode[i] != 0)
                        {
                            this.ClusterArray[0].insertNode(i);
                            if (this.ClusterNode[i] != -1)
                                this.ClusterArray[this.ClusterNode[i]].deletetNode(i);
                            this.ClusterNode[i] = 0;
                        }
                        bestCluster[i] = 0;
                        break;
                    case 1:
                        if (this.ClusterNode[i] != 1)
                        {
                            this.ClusterArray[1].insertNode(i);
                            if (this.ClusterNode[i] != -1)
                                this.ClusterArray[this.ClusterNode[i]].deletetNode(i);
                            this.ClusterNode[i] = 1;
                            bestCluster[i] = 1;
                        }
                        break;
                    case 2:
                        if (this.ClusterNode[i] != 2)
                        {
                            this.ClusterArray[2].insertNode(i);
                            if (this.ClusterNode[i] != -1)
                                this.ClusterArray[this.ClusterNode[i]].deletetNode(i);
                            this.ClusterNode[i] = 2;
                            bestCluster[i] = 2;
                        }
                        break;
                    case 3:
                        if (this.ClusterNode[i] != 3)
                        {
                            this.ClusterArray[3].insertNode(i);
                            if (this.ClusterNode[i] != -1)
                                this.ClusterArray[this.ClusterNode[i]].deletetNode(i);
                            this.ClusterNode[i] = 3;
                            bestCluster[i] = 3;
                        }
                        break;
                    case 4:
                        if (this.ClusterNode[i] != 4)
                        {
                            this.ClusterArray[4].insertNode(i);
                            if (this.ClusterNode[i] != -1)
                                this.ClusterArray[this.ClusterNode[i]].deletetNode(i);
                            this.ClusterNode[i] = 4;
                            bestCluster[i] = 4;
                        }
                        break;
                    case 5:
                        if (this.ClusterNode[i] != 5)
                        {
                            this.ClusterArray[5].insertNode(i);
                            if (this.ClusterNode[i] != -1)
                                this.ClusterArray[this.ClusterNode[i]].deletetNode(i);
                            this.ClusterNode[i] = 5;
                            bestCluster[i] = 5;
                        }
                        break;
                    case 6:
                        if (this.ClusterNode[i] != 6)
                        {
                            this.ClusterArray[6].insertNode(i);
                            if (this.ClusterNode[i] != -1)
                                this.ClusterArray[this.ClusterNode[i]].deletetNode(i);
                            this.ClusterNode[i] = 6;
                            bestCluster[i] = 6;
                        }
                        break;
                    case 7:
                        if (this.ClusterNode[i] != 7)
                        {
                            this.ClusterArray[7].insertNode(i);
                            if (this.ClusterNode[i] != -1)
                                this.ClusterArray[this.ClusterNode[i]].deletetNode(i);
                            this.ClusterNode[i] = 7;
                            bestCluster[i] = 7;
                        }
                        break;
                    case 8:
                        if (this.ClusterNode[i] != 8)
                        {
                            this.ClusterArray[8].insertNode(i);
                            if (this.ClusterNode[i] != -1)
                                this.ClusterArray[this.ClusterNode[i]].deletetNode(i);
                            this.ClusterNode[i] = 8;
                            bestCluster[i] = 8;
                        }
                        break;
                    case 9:
                        if (this.ClusterNode[i] != 9)
                        {
                            this.ClusterArray[9].insertNode(i);
                            if (this.ClusterNode[i] != -1)
                                this.ClusterArray[this.ClusterNode[i]].deletetNode(i);
                            this.ClusterNode[i] = 9;
                            bestCluster[i] = 9;
                        }
                        break;
                }

            }
        }

        public void InitialClusterForNodes_Test()
        {
            
            Random Cluster =new Random ();

                switch (numOfClusters)
                {
                    case 1:
                         for (int i = 0; i < net.numOfNodesKernel_new; i++)
                        {
                            this.ClusterNode[i] = 1;
                            this.ClusterArray[this.ClusterNode[i]].insertNode(i);
                            bestCluster[i] = this.ClusterNode[i];
                        }                    
                        break;
                    case 2:
                        for (int i = 0; i < net.numOfNodesKernel_new; i++)
                        {
                            this.ClusterNode[i] = Cluster.Next(2);
                            this.ClusterArray[this.ClusterNode[i]].insertNode(i);
                            bestCluster[i] = this.ClusterNode[i];
                        }
                        break;
                    case 3:
                        for (int i = 0; i < net.numOfNodesKernel_new; i++)
                        {
                            this.ClusterNode[i] = Cluster.Next(3);
                            this.ClusterArray[this.ClusterNode[i]].insertNode(i);
                            bestCluster[i] = this.ClusterNode[i];
                        }
                        break;
                    case 4:
                        for (int i = 0; i < net.numOfNodesKernel_new; i++)
                        {
                            this.ClusterNode[i] = Cluster.Next(4);
                            this.ClusterArray[this.ClusterNode[i]].insertNode(i);
                            bestCluster[i] = this.ClusterNode[i];
                        }
                        break;
                    case 5:
                        for (int i = 0; i < net.numOfNodesKernel_new; i++)
                        {
                            this.ClusterNode[i] = Cluster.Next(5);
                            this.ClusterArray[this.ClusterNode[i]].insertNode(i);
                            bestCluster[i] = this.ClusterNode[i];
                        }
                        break;
                    case 6:
                        for (int i = 0; i < net.numOfNodesKernel_new; i++)
                        {
                            this.ClusterNode[i] = Cluster.Next(6);
                            this.ClusterArray[this.ClusterNode[i]].insertNode(i);
                            bestCluster[i] = this.ClusterNode[i];
                        }
                        break;
                    case 7:
                        for (int i = 0; i < net.numOfNodesKernel_new; i++)
                        {
                            this.ClusterNode[i] = Cluster.Next(7);
                            this.ClusterArray[this.ClusterNode[i]].insertNode(i);
                            bestCluster[i] = this.ClusterNode[i];
                        }
                        break;
                    case 8:
                        for (int i = 0; i < net.numOfNodesKernel_new; i++)
                        {
                            this.ClusterNode[i] = Cluster.Next(8);
                            this.ClusterArray[this.ClusterNode[i]].insertNode(i);
                            bestCluster[i] = this.ClusterNode[i];
                        }
                        break;                   
                }
        }
    }
}
